import React from 'react'
import Component, { mapStateToProps, mapDispatchToProps } from '@components/Component'
import { connect } from 'react-redux'
import { Button, Table, Modal, Form, Input, Row, Col, message, TreeSelect, Select, Radio, DatePicker, Space } from 'antd'
import PropTypes from 'prop-types'
import { ExclamationCircleOutlined } from '@ant-design/icons'
import style from './Employee.module.less'
import Text from '@components/Text'
import { compress, decompress } from '@src/assets/js/tool'
import Dictionary from '@src/assets/js/dictionary'
import moment from 'moment'

const { confirm } = Modal
const { Option } = Select
const { Item } = Form

const layout = {
  labelCol: { span: 6 },
  wrapperCol: { span: 18 }
}

function getColumns () {
  return [
    {
      title: '姓名',
      dataIndex: 'name',
      ellipsis: true
    },
    {
      title: '状态',
      dataIndex: 'status',
      ellipsis: true,
      render: (value) => {
        return (
          <span>{value === 1 ? '在职' : '离职'}</span>
        )
      }
    },
    {
      title: '手机号',
      ellipsis: true,
      dataIndex: 'mobile'
    },
    {
      title: '邮箱',
      ellipsis: true,
      dataIndex: 'email'
    },
    {
      title: '文书中的电话',
      dataIndex: 'tel'
    },
    {
      title: '操作',
      dataIndex: 'id',
      render: (value, line) => {
        return (
          <span className={style['operate-line']}>
            <span onClick={() => this.modifyEmployeeBtn(line)}>修改</span>
            <span onClick={() => this.modifyRoleBtn(line)}>修改角色</span>
            <span onClick={() => this.delEmployeeHandle(line)}>删除</span>
          </span>
        )
      }
    }
  ]
}

class Employee extends Component {
  state = {
    employeeList: [],
    fileList: [],
    pagination: {
      current: 1,
      pageSize: 10,
      total: 0,
      showSizeChanger: true,
      showQuickJumper: true,
      showTotal: total => `共 ${total} 条记录`,
      size: 'small'
    },
    loading: false,
    addEmployeeModalVisible: false,
    modifyEmployeeModalVisible: false,
    modifyRoleVisible: false,
    modifyRoleAccountid: '',
    modifyRoleList: [],
    type: '全部',
    licenseTypes: []
  }

  addEmployeeFormRef = React.createRef()
  modifyEmployeeFormRef = React.createRef()
  modifyRoleFormRef = React.createRef()

  // 获取部门人员列表
  getEmployeeList () {
    const { pagination, type } = this.state
    const { currentDepartment } = this.props
    if (!currentDepartment) {
      return false
    }
    const condition = []
    if (type !== '全部') {
      condition.push({ k: 'type', o: '=', v: type })
    }
    this.setState({
      loading: true
    })
    this.$get('/api/xapc/employee', {
      structures: currentDepartment.id,
      page_size: pagination.pageSize,
      current: pagination.current,
      condition: JSON.stringify(condition)
    }).then(res => {
      this.setState({
        loading: false
      })
      if (res.status === 1) {
        this.setState({
          pagination: {
            ...this.state.pagination,
            total: res.data.total
          },
          employeeList: res.data.list.map(li => {
            if (li.mobile && typeof li.mobile === 'string') {
              li.mobile = decompress(li.mobile)
            }
            if (li.license && typeof li.license === 'string') {
              li.license = decompress(li.license)
            }
            return li
          })
        })
      } else {
        message.warning(res.message)
      }
    }).catch(() => {
      this.setState({
        loading: false
      })
    })
  }

  // 改变表格分页事件回调
  handleTableChange ({ current, pageSize }) {
    this.setState({
      pagination: {
        ...this.state.pagination,
        current,
        pageSize
      }
    }, () => {
      this.getEmployeeList()
    })
  }

  // 添加人员按钮回调
  addEmployeeHandle () {
    this.addEmployeeFormRef.current.resetFields()
    this.setState({
      addEmployeeModalVisible: true
    })
  }

  // 确定新增人员按钮回调
  decideAddEmployee () {
    this.addEmployeeFormRef.current.submit()
  }

  // 取消新增人员按钮回调
  cancelAddEmployee () {
    this.addEmployeeFormRef.current.resetFields()
    this.setState({
      addEmployeeModalVisible: false
    })
  }

  // 新增人员请求
  async addEmpolyeeRequest (data) {
    const hide = message.loading('新增人员中', 120)
    const keys = Object.keys(data)
    keys.forEach(k => {
      if (!data[k]) {
        data[k] = null
      }
    })
    delete data.digital_pic
    if (data.mobile) {
      data.mobile = compress(data.mobile)
    }
    if (data.license) {
      data.mobile = compress(data.license)
    }
    if (data.joining_datetime) {
      data.joining_datetime = Math.floor(data.joining_datetime.valueOf() / 1000)
    }
    this.$post('/api/xapc/employee', data)
      .then(res => {
        hide()
        if (res.status === 1) {
          this.getEmployeeList()
          this.addEmployeeFormRef.current.resetFields()
          this.setState({
            fileList: [],
            addEmployeeModalVisible: false
          })
        } else {
          message.warning(res.message)
        }
      }).catch(() => hide())
  }

  // 修改人员按钮回调
  modifyEmployeeBtn (data) {
    data = JSON.parse(JSON.stringify(data))
    const { digital_pic: d } = data
    let fileList = []
    if (d) {
      fileList = [{ uid: d.id, name: '签名', url: d.url, status: 'done' }]
    }
    this.setState({
      fileList,
      modifyEmployeeModalVisible: true
    }, () => {
      if (data.joining_datetime) {
        data.joining_datetime = moment(data.joining_datetime * 1000)
      }
      this.modifyEmployeeFormRef.current.setFieldsValue(data)
    })
  }

  // 修改人员角色回调
  modifyRoleBtn (data) {
    this.setState({
      modifyRoleVisible: true,
      modifyRoleAccountid: data.accountid
    }, () => {
      this.getAccountRoleList()
    })
  }

  // 根据人员账号获取人员角色
  getAccountRoleList () {
    const hide = message.loading('获取角色中', 120)
    this.$get(`/api/admin/role_access_view/${this.state.modifyRoleAccountid}`)
      .then(res => {
        hide()
        if (res.status === 1) {
          this.setState({
            modifyRoleList: res.data
          })
          this.modifyRoleFormRef.current.setFieldsValue({
            roles: res.data
          })
        } else {
          message.warning(res.message)
        }
      }).catch(() => hide())
  }

  // 确定修改人员按钮回调
  decideModiyEmployee () {
    this.modifyEmployeeFormRef.current.submit()
  }

  // 取消修改人员按钮回调
  cancelModifyEmployee () {
    this.modifyEmployeeFormRef.current.resetFields()
    this.setState({
      fileList: [],
      modifyEmployeeModalVisible: false
    })
  }

  // 修改人员请求
  async modifyEmpolyeeRequest (data) {
    const hide = message.loading('修改人员中', 120)
    const id = data.id
    delete data.id
    delete data.digital_pic
    const keys = Object.keys(data)
    keys.forEach(k => {
      if (!data[k]) {
        data[k] = null
      }
    })
    if (data.mobile) {
      data.mobile = compress(data.mobile)
    }
    if (data.license) {
      data.license = compress(data.license)
    }
    if (data.joining_datetime) {
      data.joining_datetime = Math.floor(data.joining_datetime.valueOf() / 1000)
    }
    console.log(JSON.stringify(data, undefined, 2))
    this.$put(`/api/xapc/employee/${id}`, data)
      .then(res => {
        hide()
        if (res.status === 1) {
          this.getEmployeeList()
          this.modifyEmployeeFormRef.current.resetFields()
          this.setState({
            fileList: [],
            modifyEmployeeModalVisible: false
          })
        } else {
          message.warning(res.message)
        }
      }).catch(() => hide())
  }

  // 删除人员按钮回调
  delEmployeeHandle (obj) {
    confirm({
      title: '提示',
      icon: <ExclamationCircleOutlined />,
      content: `您确定要删除 ${obj.name} 吗？`,
      onOk: () => {
        this.delEmployeeRequest(obj.id)
      }
    })
  }

  // 删除人员请求
  delEmployeeRequest (id) {
    const hide = message.loading('删除人员中', 120)
    this.$put(`/api/xapc/employee/${id}`, {
      status: 0
    }).then(res => {
      hide()
      if (res.status === 1) {
        this.getEmployeeList()
      } else {
        message.warning(res.message)
      }
    }).catch(() => hide())
  }

  modifyRoleRequest (data) {
    const origin = this.state.modifyRoleList
    const addList = []
    const delList = []
    data.roles.forEach(id => {
      if (origin.indexOf(id) === -1) {
        addList.push(id)
      }
    })
    origin.forEach(id => {
      if (data.roles.indexOf(id) === -1) {
        delList.push(id)
      }
    })
    const hide = message.loading('修改角色中', 120)
    const addRoleRequests = addList.map(id => this.addRoleRequest(id))
    const delRoleRequests = delList.map(id => this.delRoleRequest(id))
    Promise.all([...addRoleRequests, ...delRoleRequests])
      .then(() => {
        hide()
        this.setState({
          modifyRoleVisible: false
        })
        this.getEmployeeList()
      }).catch((e) => {
        hide()
        console.error(e)
        message.warning('修改角色失败')
      })
  }

  // 为账号添加角色
  addRoleRequest (id) {
    return this.$post('/api/admin/role_access_add', {
      roleid: id,
      accountid: this.state.modifyRoleAccountid,
      appid: '111'
    }).then(res => {
      if (res.status !== 1) {
        throw new Error(res.message)
      }
    })
  }

  // 为账号删除角色
  delRoleRequest (id) {
    return this.$delete('/api/admin/role_access_del', {
      accountid: this.state.modifyRoleAccountid,
      roleid: id
    })
      .then(res => {
        if (res.status !== 1) {
          throw new Error(res.message)
        }
      })
  }

  // 确定修改角色
  decideModifyRole () {
    this.modifyRoleFormRef.current.submit()
  }

  // 取消修改角色
  cancelModifyRole () {
    this.setState({
      modifyRoleVisible: false,
      modifyRoleList: [],
      modifyRoleAccountid: ''
    }, () => {
      this.modifyRoleFormRef.current.resetFields()
    })
  }

  validator (rule, value) {
    if (!value) {
      return Promise.resolve()
    }
    if (value.length < 8) {
      return Promise.reject(new Error('最小长度为8位'))
    }
    let count = 0
    if (/[$-]+/.test(value)) {
      return Promise.reject(new Error('密码不能包含-和$'))
    }
    if (/[a-z]+/.test(value) && /[A-Z]+/.test(value)) {
      count++
    }
    if (/[~!@#%^&*()_+=*/<>?/\\.,;'"]+/.test(value)) {
      count++
    }
    if (/[0-9]+/.test(value)) {
      count++
    }
    if (count < 2) {
      return Promise.reject(new Error('密码必须包含大小写字母+数字+特殊符号中的两种以上'))
    }
    return Promise.resolve()
  }

  componentDidUpdate (prev) {
    if (prev.currentDepartment !== this.props.currentDepartment) {
      this.getEmployeeList()
    }
  }

  componentDidMount () {
    const d = new Dictionary()
    d.init('自然人证件类型')
      .then(() => {
        this.setState({
          licenseTypes: d.getList('自然人证件类型').map(li => ({ label: li.titie, value: li.title }))
        })
      })
  }

  // 渲染新增人员详情
  renderAddEmployeeModal () {
    let structures = ''
    if (this.props.currentDepartment) {
      structures = this.props.currentDepartment.id
    }
    const data = {
      structures
    }
    return (
      <Modal
        width={800}
        title='添加人员'
        forceRender
        open={this.state.addEmployeeModalVisible}
        maskClosable={false}
        onOk={() => this.decideAddEmployee()}
        onCancel={() => this.cancelAddEmployee()}
      >
        <Form name='add_employee' {...layout} ref={this.addEmployeeFormRef} initialValues={data} onFinish={v => this.addEmpolyeeRequest(v)}>
          <Row>
            <Col span={12}>
              <Item name='username' label='登录账户' rules={[{ required: true, message: '登录账户不能为空' }]}>
                <Input placeholder='请输入登录账户' />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='password' label='密码' rules={[{ required: true, message: '密码不能为空' }, { validator: this.validator }]}>
                <Input placeholder='请输入密码' />
              </Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Item name='name' label='姓名' rules={[{ required: true, message: '姓名不能为空' }]}>
                <Input placeholder='请输入姓名' />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='mobile' label='手机号' rules={[{ required: true, message: '手机号不能为空' }]}>
                <Input placeholder='请输入手机号' />
              </Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Item name='tel' label='固定电话' rules={[{ required: true, message: '固定电话不能为空' }]}>
                <Input placeholder='请输入固定电话' />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='email' label='邮箱' rules={[{ required: true, message: '邮箱不能为空' }]}>
                <Input placeholder='请输入邮箱' />
              </Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Item name='structures' label='部门' rules={[{ required: true, message: '部门不能为空' }]}>
                <TreeSelect showSearch placeholder='请选择部门' treeDefaultExpandAll allowClear treeData={this.props.departmentTreeData} />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='educational' label='学历'>
                <Select placeholder='请选择'>
                  <Option value='专科'>专科</Option>
                  <Option value='本科'>本科</Option>
                  <Option value='硕士研究生'>硕士研究生</Option>
                  <Option value='博士研究生'>博士研究生</Option>
                </Select>
              </Item>
            </Col>
            <Col span={12}>
              <Item name='license_type' label='证件类型'>
                <Select placeholder='请选择' options={this.state.licenseTypes} />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='license' label='证件号'>
                <Input placeholder='请输入' />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='joining_datetime' label='入职时间'>
                <DatePicker placeholder='请选择' className={style.full} />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='gender' label='性别'>
                <Radio.Group options={['男', '女']} />
              </Item>
            </Col>
          </Row>
        </Form>
      </Modal>
    )
  }

  // 渲染修改人员详情
  renderModifyEmployeeModal () {
    return (
      <Modal
        width={800}
        title='修改人员'
        forceRender
        open={this.state.modifyEmployeeModalVisible}
        maskClosable={false}
        onOk={() => this.decideModiyEmployee()}
        onCancel={() => this.cancelModifyEmployee()}
      >
        <Form name='modify_employee' {...layout} ref={this.modifyEmployeeFormRef} onFinish={v => this.modifyEmpolyeeRequest(v)}>
          <Item name='id' noStyle><span /></Item>
          <Item name='status' noStyle><span /></Item>
          <Row>
            <Col span={12}>
              <Item name='username' label='登录账户' rules={[{ required: true, message: '登录账户不能为空' }]}>
                <Text />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='password' label='密码' rules={[{ validator: this.validator }]}>
                <Input placeholder='请输入密码' />
              </Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Item name='name' label='姓名' rules={[{ required: true, message: '姓名不能为空' }]}>
                <Input placeholder='请输入姓名' />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='mobile' label='手机号' rules={[{ required: true, message: '手机号不能为空' }]}>
                <Input placeholder='请输入手机号' />
              </Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Item name='tel' label='固定电话' rules={[{ required: true, message: '固定电话不能为空' }]}>
                <Input placeholder='请输入固定电话' />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='email' label='邮箱' rules={[{ required: true, message: '邮箱不能为空' }]}>
                <Input placeholder='请输入邮箱' />
              </Item>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <Item name='structures' label='部门' rules={[{ required: true, message: '部门不能为空' }]}>
                <TreeSelect showSearch placeholder='请选择部门' treeDefaultExpandAll allowClear treeData={this.props.departmentTreeData} />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='educational' label='学历'>
                <Select placeholder='请选择'>
                  <Option value='专科'>专科</Option>
                  <Option value='本科'>本科</Option>
                  <Option value='硕士研究生'>硕士研究生</Option>
                  <Option value='博士研究生'>博士研究生</Option>
                </Select>
              </Item>
            </Col>
            <Col span={12}>
              <Item name='license_type' label='证件类型'>
                <Select placeholder='请选择' options={this.state.licenseTypes} />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='license' label='证件号'>
                <Input placeholder='请输入' />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='joining_datetime' label='入职时间'>
                <DatePicker placeholder='请选择' className={style.full} />
              </Item>
            </Col>
            <Col span={12}>
              <Item name='gender' label='性别'>
                <Radio.Group options={['男', '女']} />
              </Item>
            </Col>
          </Row>
        </Form>
      </Modal>
    )
  }

  // 渲染修改角色块
  renderModifyRole () {
    return (
      <Modal
        width={800}
        title='修改角色'
        forceRender
        open={this.state.modifyRoleVisible}
        maskClosable={false}
        onOk={() => this.decideModifyRole()}
        onCancel={() => this.cancelModifyRole()}
      >
        <Form name='modify_employee_role' {...layout} ref={this.modifyRoleFormRef} onFinish={v => this.modifyRoleRequest(v)}>
          <Item name='roles' label='角色' rules={[{ required: true, message: '角色不能为空' }]}>
            <Select mode='multiple' placeholder='请选择角色'>
              {
                this.props.roleList.map(li => (
                  <Option key={li.id}>{li.name}</Option>
                ))
              }
            </Select>
          </Item>
        </Form>
      </Modal>
    )
  }

  render () {
    const options = this.props.typeOptions.map(li => li.label)
    return (
      <>
        {this.renderAddEmployeeModal()}
        {this.renderModifyEmployeeModal()}
        {this.renderModifyRole()}
        <div className={style['department-title-line']}>
          <span>{(this.props.currentDepartment || {}).name}</span>
          <span>{(this.state.pagination.total)} (人）</span>
        </div>
        <div className={style['employee-line']}>
          <Space>
            <Button type='primary' onClick={() => this.addEmployeeHandle()}>+ 添加人员</Button>
            <Radio.Group options={['全部', ...options]} optionType='button' value={this.state.type} onChange={e => this.setState({ type: e.target.value }, () => { this.getEmployeeList() })} />
          </Space>
        </div>
        <Table
          columns={getColumns.call(this)}
          rowKey={record => record.id}
          dataSource={this.state.employeeList}
          pagination={this.state.pagination}
          loading={this.state.loading}
          onChange={(...args) => { this.handleTableChange(...args) }}
        />
      </>
    )
  }
}

Employee.proptypes = {
  currentDepartment: PropTypes.object,
  roleList: PropTypes.array,
  roleMap: PropTypes.object,
  departmentTreeData: PropTypes.array,
  typeOptions: PropTypes.array
}

Employee.defaultProps = {
  currentDepartment: null,
  roleList: [],
  roleMap: {},
  departmentTreeData: [],
  typeOptions: []
}

const mapState = mapStateToProps(function (state) {
  return {
    userInfo: state.basic.userInfo
  }
})

const mapDispatch = mapDispatchToProps(function (dispatch) {
  return {

  }
})

export default connect(mapState, mapDispatch)(Employee)
